package com.yunpeng.aidevice.dao.service.impl;

import com.yunpeng.aidevice.common.constant.ConfigConstantValues;
import com.yunpeng.aidevice.dao.service.ICodeGenerateCommonService;
import com.yunpeng.aidevice.dao.service.IRoleService;
import com.yunpeng.aidevice.common.enums.ResultCodeEnum;
import com.yunpeng.cache.util.DistributedLockHelper;
import com.yunpeng.common.exception.BizException;
import com.yunpeng.aidevice.dao.constant.DictionariesConstant;
import com.yunpeng.aidevice.dao.mapper.entity.PermissionMapper;
import com.yunpeng.aidevice.dao.mapper.entity.RoleMapper;
import com.yunpeng.aidevice.dao.mapper.entity.UserMapper;
import com.yunpeng.aidevice.dao.mapper.relation.RolePermissionMapper;
import com.yunpeng.aidevice.dao.mapper.relation.UserRoleMapper;
import com.yunpeng.aidevice.dao.model.entity.PermissionDO;
import com.yunpeng.aidevice.dao.model.entity.RoleDO;
import com.yunpeng.aidevice.dao.model.entity.UserDO;
import com.yunpeng.aidevice.dao.model.relation.RolePermissionDO;
import com.yunpeng.aidevice.dao.model.relation.UserRoleDO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * RoleServiceImpl
 *
 * @author : Moore(hemw)
 * @date : 2020-04-15
 */
@Service
public class RoleServiceImpl implements IRoleService {

    /**
     * 日志对象
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(RoleServiceImpl.class);

    /**
     * 当前服务的实体表名
     */
    private static final String TABLE_NAME = "t_ai_device_role";

    @Resource
    private ICodeGenerateCommonService codeGenerateCommonService;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserRoleMapper userRoleMapper;


    @Override
    /**
     * 根据角色代码获取角色对象
     *
     * @param roleCode 角色代码
     * @return
     */
    public RoleDO getByCode(String roleCode) {
        if (StringUtils.isBlank(roleCode)) {
            return null;
        }
        return roleMapper.getByCode(roleCode);
    }

    @Override
    /**
     * 统计权限关联角色数量
     *
     * @param permissionCode 二选一
     * @param roleCode       二选一
     * @return
     */
    public Integer countPermissionRelation(String permissionCode, String roleCode) {
        if (StringUtils.isBlank(roleCode) && StringUtils.isBlank(permissionCode)) {
            throw new BizException(ResultCodeEnum.PARAMETER_CHECK_FAILED, "必须有一个不为空");
        }
        return rolePermissionMapper.existsCount(permissionCode, roleCode);
    }

    @Override
    /**
     * 新增角色
     *
     * @param roleName     角色名称
     * @param operatorCode 操作人代码
     * @return
     */
    public Boolean addNew(String roleName, String operatorCode) {
        if (StringUtils.isBlank(roleName)) {
            return false;
        }
        RoleDO roleDO = new RoleDO();
        roleDO.initForNew(operatorCode);
        roleDO.setName(roleName);

        if (DistributedLockHelper.INSTANCE.getLock(TABLE_NAME, ConfigConstantValues.APPLICATION_NAME)) {
            roleDO.setCode(codeGenerateCommonService.generateCode(TABLE_NAME));
            try {
                roleMapper.add(roleDO);
                return true;
            } catch (Exception ex) {
                LOGGER.error("save role info error : {}", roleDO, ex);
                throw new BizException(ResultCodeEnum.SAVE_DATA_FAILED);
            } finally {
                codeGenerateCommonService.holdCountMinus(TABLE_NAME);
                DistributedLockHelper.INSTANCE.unlock(TABLE_NAME, ConfigConstantValues.APPLICATION_NAME);
            }
        } else {
            return false;
        }
    }

    @Override
    /**
     * 删除角色
     *
     * @param roleCode 角色代码
     * @return
     */
    public Boolean remove(String roleCode) {
        if (StringUtils.isBlank(roleCode)) {
            return false;
        }
        RoleDO roleDO = roleMapper.getByCode(roleCode);
        if (roleDO == null || roleDO.getId() == null) {
            return true;
        }
        roleMapper.delete(roleDO.getId());
        rolePermissionMapper.deleteByRoleCode(roleCode);
        return true;
    }

    @Override
    /**
     * 绑定权限角色
     *
     * @param roleCode       角色代码
     * @param permissionCode 权限代码
     * @param operatorCode   操作人代码
     * @return
     */
    public Boolean bindPermission(String roleCode, String permissionCode, String operatorCode) {
        if (StringUtils.isBlank(roleCode)) {
            return false;
        }
        if (StringUtils.isBlank(permissionCode)) {
            return false;
        }
        //已经存在绑定，直接返回
        if (countPermissionRelation(permissionCode, roleCode) > 0) {
            return true;
        }
        RoleDO roleDO = roleMapper.getByCode(roleCode);
        if (roleDO == null || roleDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "角色不存在");
        }
        PermissionDO permissionDO = permissionMapper.getByCode(permissionCode);
        if (permissionDO == null || permissionDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "权限不存在");
        }
        RolePermissionDO rolePermissionDO = new RolePermissionDO();
        rolePermissionDO.initForNew(operatorCode);
        rolePermissionDO.setPermissionCode(permissionDO.getCode());
        rolePermissionDO.setPermissionName(permissionDO.getName());
        rolePermissionDO.setRoleCode(roleDO.getCode());
        rolePermissionDO.setRoleName(roleDO.getName());

        rolePermissionMapper.add(rolePermissionDO);
        return true;
    }

    @Override
    /**
     * 解绑角色权限
     *
     * @param roleCode       角色代码
     * @param permissionCode 权限代码
     * @return
     */
    public Boolean unbindPermission(String roleCode, String permissionCode) {
        if (StringUtils.isBlank(roleCode)) {
            return false;
        }
        if (StringUtils.isBlank(permissionCode)) {
            return false;
        }
        rolePermissionMapper.deleteByRoleAndPermission(roleCode, permissionCode);
        return true;
    }

    @Override
    /**
     * 用户绑定角色
     *
     * @param roleCode     角色代码
     * @param userCode     用户代码
     * @param startTime    起始生效时间
     * @param endTime      生效截止时间
     * @param operatorCode 操作人代码
     * @return
     */
    public Boolean userBindRole(String roleCode, String userCode, Date startTime, Date endTime, String operatorCode) {
        if (StringUtils.isBlank(roleCode)) {
            return false;
        }
        if (StringUtils.isBlank(userCode)) {
            return false;
        }
        RoleDO roleDO = roleMapper.getByCode(roleCode);
        if (roleDO == null || roleDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "角色不存在");
        }
        UserDO userDO = userMapper.getByCode(userCode);
        if (userDO == null || userDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "用户不存在");
        }
        UserRoleDO userRoleDO = new UserRoleDO();
        userRoleDO.initForNew(operatorCode);
        userRoleDO.setUserCode(userDO.getCode());
        userRoleDO.setUserName(userDO.getName());
        userRoleDO.setRoleName(roleDO.getName());
        userRoleDO.setRoleCode(roleDO.getCode());
        userRoleDO.setStartDate(startTime);
        userRoleDO.setEndDate(endTime);
        userRoleMapper.add(userRoleDO);
        return true;
    }

    @Override
    /**
     * 解除用户角色绑定
     *
     * @param roleCode 角色代码
     * @param userCode 用户代码
     * @return
     */
    public Boolean userUnBindRole(String roleCode, String userCode) {
        if (StringUtils.isBlank(roleCode)) {
            return false;
        }
        if (StringUtils.isBlank(userCode)) {
            return false;
        }
        userRoleMapper.deleteByUserRole(userCode, roleCode);
        return true;
    }

    @Override
    /**
     * 统计用户角色数量 （有效中）
     *
     * @param roleCode 角色代码
     * @param userCode 用户代码
     * @return
     */
    public Integer existUserRoleCount(String roleCode, String userCode) {
        if (StringUtils.isBlank(roleCode) && StringUtils.isBlank(userCode)) {
            throw new BizException(ResultCodeEnum.PARAMETER_CHECK_FAILED, "必须有一个不为空");
        }
        return userRoleMapper.existsCount(roleCode, userCode, new Date());
    }

    @Override
    /**
     * 查询当前用户和角色关联数据 （生效的）
     *
     * @param roleCode 角色代码
     * @return
     */
    public List<UserRoleDO> queryUserRoleListByRole(String roleCode) {
        if (StringUtils.isBlank(roleCode)) {
            return null;
        }
        return userRoleMapper.queryRelationListByRole(roleCode, new Date());
    }


    @Override
    /**
     * 验证用户编辑用户信息权限
     *
     * @param userCode
     * @param loginUserCode
     * @return
     */
    public Boolean checkUpdateAnotherUserInfo(String userCode, String loginUserCode) {
        Date now = new Date();
        if (userRoleMapper.existsCount(DictionariesConstant.INSTANCE.getAdminRoleName(), loginUserCode, now) > 0) {
            return true;
        }
        if (userRoleMapper.existsCount(DictionariesConstant.INSTANCE.getOperateAdminRoleName(), loginUserCode, now) > 0) {
            return true;
        }
        return userCode.equalsIgnoreCase(loginUserCode);
    }

    @Override
    /**
     * 验证用户是否具有某种角色
     *
     * @param roleCode 角色代码
     * @param userCode 用户代码
     * @return
     */
    public Boolean checkUserRole(String roleCode, String userCode) {
        if (userRoleMapper.existsCount(roleCode, userCode, new Date()) > 0) {
            return true;
        }
        return false;
    }
}
